package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.handler;


import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.NettyByteBuf;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.constant.ProxyMessageType;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;


@Slf4j
public class NettySocksClientProxyServerVisitorInboundHandler extends SimpleChannelInboundHandler<NettyByteBuf> {

    private final Channel transferChannel;

    public NettySocksClientProxyServerVisitorInboundHandler(Channel transferChannel) {
        this.transferChannel = transferChannel;
    }


    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER);
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, NettyByteBuf nettyByteBuf) throws Exception {
        log.info("【socks】转发客户端的请求到代理服务器");
        // 结果下发
        Channel channel = ctx.channel();
        byte[] bytes = nettyByteBuf.getData();
        log.debug("bytes.length:{}",bytes.length);
        log.debug("客户端代理服务端,socks本地接收请求数据:{}", new String(bytes));
        Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);

        if (nextChannel.isActive()) {
            // 上传数据到服务端
            NettyProxyMsg nettyProxyMsg = new NettyProxyMsg();
            nettyProxyMsg.setType(ProxyMessageType.SOCKS_REPORT_CLIENT_PROXY_SERVER_TRANSFER_REQUEST_);

            nettyProxyMsg.setData(nettyByteBuf.getData());
            nextChannel.writeAndFlush(nettyProxyMsg);
        } else {
            log.info("释放内存");
            ReferenceCountUtil.release(nettyByteBuf);
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("【socks】客户端与代理服务器的连接已经断开，即将断开代理服务器和目标服务器的连接");
        Channel channel = ctx.channel();
        Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
        if (nextChannel.isActive()) {
            // 上报断开链接
            NettyProxyMsg nettyProxyMsgTransferClose = new NettyProxyMsg();
            nettyProxyMsgTransferClose.setType(ProxyMessageType.SOCKS_REPORT_CLIENT_PROXY_SERVER_TRANSFER_CLOSE_);
            nextChannel.writeAndFlush(nettyProxyMsgTransferClose);
            if (ctx.channel().isActive()) {
                ctx.channel().writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("【socks】NettySocksClientProxyServerVisitorInboundHandler exception", cause);
        ctx.close();
    }
}
